package com.woniuxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.client.FlowableFeign;
import com.woniuxy.client.UserFeign;
import com.woniuxy.dto.ResponseData;
import org.springframework.data.domain.PageImpl;
import com.woniuxy.dto.CustomerApplicationDto;
import com.woniuxy.dto.CustomerApprovalDto;
import com.woniuxy.dto.CustomerProcessDto;
import com.woniuxy.entity.*;
import com.woniuxy.mapper.*;
import com.woniuxy.service.CustomerApplicationService;
import com.woniuxy.client.CustomerFlowableClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 客户申请服务实现类
 */
@Slf4j
@Service
@Transactional
public class CustomerApplicationServiceImpl implements CustomerApplicationService {
    @Autowired
    private FlowableFeign flowableFeign;
    @Autowired
    private UserFeign userFeign;

    @Autowired
    private CustomerBasicInfoMapper customerBasicInfoMapper;

    @Autowired
    private CustomerDeliveryInfoMapper customerDeliveryInfoMapper;

    @Autowired
    private CustomerInvoiceInfoMapper customerInvoiceInfoMapper;

    @Autowired
    private CustomerOrderUnitInfoMapper customerOrderUnitInfoMapper;

    @Autowired
    private CustomerApprovalRecordMapper customerApprovalRecordMapper;

    @Autowired
    private CustomerStatusLogMapper customerStatusLogMapper;

    @Autowired
    private CustomerFlowableClient customerFlowableClient;

    @Override
    public CustomerBasicInfo createCustomerApplication(CustomerApplicationDto applicationDto, String currentUser) {
        CustomerBasicInfo customerBasicInfo = new CustomerBasicInfo();
        BeanUtils.copyProperties(applicationDto, customerBasicInfo);

        // 设置初始状态
        customerBasicInfo.setApprovalStatus("PENDING");
        customerBasicInfo.setCreatedAt(new Date());
        customerBasicInfo.setUpdatedAt(new Date());
        customerBasicInfo.setCreateBy(currentUser);
        customerBasicInfo.setUpdateBy(currentUser);

        // 保存基本信息
        customerBasicInfoMapper.insert(customerBasicInfo);

        // 保存收货信息
        if (applicationDto.getDeliveryName() != null) {
            CustomerDeliveryInfo deliveryInfo = new CustomerDeliveryInfo();
            deliveryInfo.setCustomerId(customerBasicInfo.getId());
            deliveryInfo.setDeliveryName(applicationDto.getDeliveryName());
            deliveryInfo.setDeliveryPhone(applicationDto.getDeliveryPhone());
            deliveryInfo.setDeliveryAddress(applicationDto.getDeliveryAddress());
            deliveryInfo.setProvince(applicationDto.getProvince());
            deliveryInfo.setCity(applicationDto.getCity());
            deliveryInfo.setDistrict(applicationDto.getDistrict());
            deliveryInfo.setApprovalStatus("PENDING");
            deliveryInfo.setCreatedAt(new Date());
            deliveryInfo.setUpdatedAt(new Date());
            customerDeliveryInfoMapper.insert(deliveryInfo);
        }

        // 保存开票信息
        if (applicationDto.getInvoiceTitle() != null) {
            CustomerInvoiceInfo invoiceInfo = new CustomerInvoiceInfo();
            invoiceInfo.setCustomerId(customerBasicInfo.getId());
            invoiceInfo.setInvoiceTitle(applicationDto.getInvoiceTitle());
            invoiceInfo.setTaxNumber(applicationDto.getTaxNumber());
            invoiceInfo.setBankName(applicationDto.getBankName());
            invoiceInfo.setBankAccount(applicationDto.getBankAccount());
            invoiceInfo.setApprovalStatus("PENDING");
            invoiceInfo.setCreatedAt(new Date());
            invoiceInfo.setUpdatedAt(new Date());
            customerInvoiceInfoMapper.insert(invoiceInfo);
        }

        // 保存订货单位信息
        if (applicationDto.getOrderUnitName() != null) {
            CustomerOrderUnitInfo orderUnitInfo = new CustomerOrderUnitInfo();
            orderUnitInfo.setCustomerId(customerBasicInfo.getId());
            orderUnitInfo.setOrderUnitName(applicationDto.getOrderUnitName());
            orderUnitInfo.setAddress(applicationDto.getAddress());
            orderUnitInfo.setContactPerson(applicationDto.getOrderContactPerson());
            orderUnitInfo.setPhone(applicationDto.getOrderPhone());
            orderUnitInfo.setApprovalStatus("PENDING");
            orderUnitInfo.setCreatedAt(new Date());
            orderUnitInfo.setUpdatedAt(new Date());
            customerOrderUnitInfoMapper.insert(orderUnitInfo);
        }

        // 记录状态变更日志
        saveCustomerStatusLog(customerBasicInfo.getId(), customerBasicInfo.getCustomerName(),
                null, "PENDING", "创建客户申请", currentUser);

        log.info("创建客户申请成功，客户ID：{}，客户名称：{}", customerBasicInfo.getId(), customerBasicInfo.getCustomerName());
        return customerBasicInfo;
    }

    @Override
    public CustomerBasicInfo updateCustomerApplication(Long customerId, CustomerApplicationDto applicationDto, String currentUser) {
        CustomerBasicInfo customer = customerBasicInfoMapper.selectById(customerId);
        if (customer == null) {
            throw new RuntimeException("客户不存在");
        }

        // 更新基本信息
        BeanUtils.copyProperties(applicationDto, customer);
        customer.setUpdatedAt(new Date());
        customerBasicInfoMapper.updateById(customer);

        // 更新收货信息
        CustomerDeliveryInfo deliveryInfo = customerDeliveryInfoMapper.selectOne(
                new QueryWrapper<CustomerDeliveryInfo>().eq("customer_id", customerId));
        if (deliveryInfo != null) {
            deliveryInfo.setDeliveryName(applicationDto.getDeliveryName());
            deliveryInfo.setDeliveryPhone(applicationDto.getDeliveryPhone());
            deliveryInfo.setDeliveryAddress(applicationDto.getDeliveryAddress());
            deliveryInfo.setProvince(applicationDto.getProvince());
            deliveryInfo.setCity(applicationDto.getCity());
            deliveryInfo.setDistrict(applicationDto.getDistrict());
            deliveryInfo.setUpdatedAt(new Date());
            customerDeliveryInfoMapper.updateById(deliveryInfo);
        }

        // 更新开票信息
        CustomerInvoiceInfo invoiceInfo = customerInvoiceInfoMapper.selectOne(
                new QueryWrapper<CustomerInvoiceInfo>().eq("customer_id", customerId));
        if (invoiceInfo != null) {
            invoiceInfo.setInvoiceTitle(applicationDto.getInvoiceTitle());
            invoiceInfo.setTaxNumber(applicationDto.getTaxNumber());
            invoiceInfo.setBankName(applicationDto.getBankName());
            invoiceInfo.setBankAccount(applicationDto.getBankAccount());
            invoiceInfo.setUpdatedAt(new Date());
            customerInvoiceInfoMapper.updateById(invoiceInfo);
        }

        // 更新订货单位信息
        CustomerOrderUnitInfo orderUnitInfo = customerOrderUnitInfoMapper.selectOne(
                new QueryWrapper<CustomerOrderUnitInfo>().eq("customer_id", customerId));
        if (orderUnitInfo != null) {
            orderUnitInfo.setOrderUnitName(applicationDto.getOrderUnitName());
            orderUnitInfo.setAddress(applicationDto.getAddress());
            orderUnitInfo.setContactPerson(applicationDto.getOrderContactPerson());
            orderUnitInfo.setPhone(applicationDto.getOrderPhone());
            orderUnitInfo.setUpdatedAt(new Date());
            customerOrderUnitInfoMapper.updateById(orderUnitInfo);
        }

        log.info("更新客户申请成功，客户ID：{}，客户名称：{}", customerId, customer.getCustomerName());
        return customer;
    }

    @Override
    public void deleteCustomerApplication(Long customerId, String currentUser) {
        CustomerBasicInfo customer = customerBasicInfoMapper.selectById(customerId);
        if (customer == null) {
            throw new RuntimeException("客户不存在");
        }

        // 删除相关数据
        customerDeliveryInfoMapper.delete(new QueryWrapper<CustomerDeliveryInfo>().eq("customer_id", customerId));
        customerInvoiceInfoMapper.delete(new QueryWrapper<CustomerInvoiceInfo>().eq("customer_id", customerId));
        customerOrderUnitInfoMapper.delete(new QueryWrapper<CustomerOrderUnitInfo>().eq("customer_id", customerId));
        customerApprovalRecordMapper.delete(new QueryWrapper<CustomerApprovalRecord>().eq("customer_id", customerId));
        customerStatusLogMapper.delete(new QueryWrapper<CustomerStatusLog>().eq("customer_id", customerId));
        customerBasicInfoMapper.deleteById(customerId);

        log.info("删除客户申请成功，客户ID：{}，客户名称：{}", customerId, customer.getCustomerName());
    }

    @Override
    public CustomerBasicInfo getCustomerApplicationById(Long customerId) {
        return customerBasicInfoMapper.selectById(customerId);
    }

    @Override
    public com.woniuxy.dto.CustomerDetailDto getCustomerDetailById(Long customerId) {
        // 获取基本信息
        CustomerBasicInfo basicInfo = customerBasicInfoMapper.selectById(customerId);
        if (basicInfo == null) {
            throw new RuntimeException("客户不存在");
        }

        // 获取收货信息
        CustomerDeliveryInfo deliveryInfo = customerDeliveryInfoMapper.selectOne(
                new QueryWrapper<CustomerDeliveryInfo>().eq("customer_id", customerId));

        // 获取开票信息
        CustomerInvoiceInfo invoiceInfo = customerInvoiceInfoMapper.selectOne(
                new QueryWrapper<CustomerInvoiceInfo>().eq("customer_id", customerId));

        // 获取订货单位信息
        CustomerOrderUnitInfo orderUnitInfo = customerOrderUnitInfoMapper.selectOne(
                new QueryWrapper<CustomerOrderUnitInfo>().eq("customer_id", customerId));

        // 构建详情DTO
        return com.woniuxy.dto.CustomerDetailDto.fromEntities(basicInfo, deliveryInfo, invoiceInfo, orderUnitInfo);
    }

    @Override
    public org.springframework.data.domain.Page<CustomerBasicInfo> getCustomerApplications(Pageable pageable, String customerName, String approvalStatus, String currentUser) {
        QueryWrapper<CustomerBasicInfo> queryWrapper = new QueryWrapper<>();

        if (customerName != null && !customerName.trim().isEmpty()) {
            queryWrapper.like("customer_name", customerName);
        }
        if (approvalStatus != null && !approvalStatus.trim().isEmpty()) {
            queryWrapper.eq("approval_status", approvalStatus);
        }

        queryWrapper.orderByDesc("created_at");

        com.baomidou.mybatisplus.extension.plugins.pagination.Page<CustomerBasicInfo> mpPage =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(
                        pageable.getPageNumber() + 1, pageable.getPageSize());

        com.baomidou.mybatisplus.extension.plugins.pagination.Page<CustomerBasicInfo> result =
                customerBasicInfoMapper.selectPage(mpPage, queryWrapper);

        return new PageImpl<CustomerBasicInfo>(result.getRecords(), pageable, result.getTotal());
    }

    @Override
    public List<CustomerBasicInfo> getUserCustomerApplications(String currentUser) {
        QueryWrapper<CustomerBasicInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("created_at");
        return customerBasicInfoMapper.selectList(queryWrapper);
    }

    @Override
    public List<CustomerBasicInfo> getPendingCustomerApplications(String currentUser) {
        try {
            // 1. 获取待办任务
            ResponseData<?> pendingTasks = flowableFeign.getPendingTasks(currentUser);

            if (!pendingTasks.isSuccess() || pendingTasks.getData() == null) {
                log.warn("获取待办任务失败或无数据，用户：{}", currentUser);
                return new ArrayList<>();
            }

            // 2. 从ResponseData中提取数据
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> taskList = (List<Map<String, Object>>) pendingTasks.getData();

            if (taskList.isEmpty()) {
                log.info("用户 {} 没有待办任务", currentUser);
                return new ArrayList<>();
            }

            // 3. 提取所有的processInstanceId
            List<String> processInstanceIds = taskList.stream()
                    .map(task -> (String) task.get("processInstanceId"))
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            if (processInstanceIds.isEmpty()) {
                log.warn("待办任务中没有有效的processInstanceId，用户：{}", currentUser);
                return new ArrayList<>();
            }

            log.info("用户 {} 的待办任务包含 {} 个流程实例ID：{}", currentUser, processInstanceIds.size(), processInstanceIds);

            // 4. 根据processInstanceId查询CustomerBasicInfo
            QueryWrapper<CustomerBasicInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("process_instance_id", processInstanceIds);
            queryWrapper.orderByDesc("created_at");

            List<CustomerBasicInfo> customers = customerBasicInfoMapper.selectList(queryWrapper);

            log.info("根据流程实例ID查询到 {} 个客户信息", customers.size());
            return customers;

        } catch (Exception e) {
            log.error("获取待审批客户列表失败，用户：{}", currentUser, e);
            throw new RuntimeException("获取待审批客户列表失败: " + e.getMessage(), e);
        }
    }

    @Override
    public String submitCustomerApplication(Long customerId, String currentUser) {
        CustomerBasicInfo customer = customerBasicInfoMapper.selectById(customerId);
        if (customer == null) {
            throw new RuntimeException("客户不存在");
        }

        // 准备流程变量
        Map<String, Object> variables = new HashMap<>();
        variables.put("customerId", String.valueOf(customer.getId()));
        variables.put("customerName", customer.getCustomerName());
        variables.put("applicant", currentUser);
        variables.put("callbackUrl", "http://localhost:8001/api/customers/callback");

        // 设置审批人信息
        List<String> regionalManagerGroup = userFeign.getRm(currentUser);
        variables.put("regionalManagerGroup", String.join(",", regionalManagerGroup));
        variables.put("areaManagerId", "regional_director"); // 大区经理用户名
        variables.put("creditControlId", "credit_control_group"); // 信用控制组用户名
        variables.put("salesDirectorId", "sales_director"); // 销售总监用户名
        variables.put("businessId", "company_business"); // 公司商务用户名

        try {
            // 调用 Flowable 服务启动流程
            String processInstanceId = customerFlowableClient.startProcess(
                    "NewCustomer",  // 流程定义Key
                    String.valueOf(customer.getId()),  // 业务Key
                    variables
            );

            // 更新客户状态
            customer.setProcessInstanceId(processInstanceId);
            customer.setApprovalStatus("APPROVING");
            customer.setUpdatedAt(new Date());

            customerBasicInfoMapper.updateById(customer);


            // 记录状态变更日志
            saveCustomerStatusLog(customer.getId(), customer.getCustomerName(), "PENDING",
                    "APPROVING", "提交审批流程", currentUser);

            log.info("提交客户审批成功，客户ID：{}，客户名称：{}，流程实例ID：{}",
                    customer.getId(), customer.getCustomerName(), processInstanceId);
            return processInstanceId;

        } catch (Exception e) {
            log.error("启动客户审批工作流失败", e);
            throw new RuntimeException("提交审批失败: " + e.getMessage());
        }
    }

    @Override
    public void approveCustomer(String processInstanceId, String currentUser) {
        ResponseData<?> responseData = flowableFeign.approveTask(processInstanceId);
        //根据processInstanceId修改当前审批人为currentUser
        Integer integer = customerBasicInfoMapper.updateByProcessInstanceId(processInstanceId, currentUser);
    }

    @Override
    public CustomerProcessDto getCustomerProcess(Long customerId) {
        CustomerBasicInfo customer = customerBasicInfoMapper.selectById(customerId);
        if (customer == null) {
            return null;
        }

        CustomerProcessDto dto = new CustomerProcessDto();
        dto.setProcessInstanceId(customer.getProcessInstanceId());
        dto.setProcessStatus(customer.getApprovalStatus());
        dto.setCurrentStep(customer.getCurrentStep());
        dto.setCurrentApprover(customer.getCurrentApprover());

        return dto;
    }

    @Override
    public List<CustomerProcessDto.ProcessStepDto> getCustomerProcessSteps(String processInstanceId) {
        // 使用XML中的自定义查询方法
        QueryWrapper<CustomerApprovalRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("process_instance_id", processInstanceId);
        List<CustomerApprovalRecord> records = customerApprovalRecordMapper.selectList(queryWrapper);

        return records.stream().map(record -> {
            CustomerProcessDto.ProcessStepDto stepDto = new CustomerProcessDto.ProcessStepDto();
            stepDto.setTaskId(record.getTaskId());
            stepDto.setTaskName(record.getApprovalStep());
            stepDto.setAssignee(record.getApproverName());
            stepDto.setStatus("COMPLETED");
            stepDto.setComment(record.getApprovalComment());
            stepDto.setResult(record.getApprovalResult());
            if (record.getApprovalTime() != null) {
                stepDto.setEndTime(record.getApprovalTime().toString());
            }
            return stepDto;
        }).collect(Collectors.toList());
    }

    @Override
    public Map<String, Object> getCustomerStatistics(String currentUser) {
        Map<String, Object> statistics = new HashMap<>();

        // 统计各状态客户数量
        long totalCount = customerBasicInfoMapper.selectCount(null);
        long pendingCount = customerBasicInfoMapper.selectCount(
                new QueryWrapper<CustomerBasicInfo>().eq("approval_status", "PENDING"));
        long approvingCount = customerBasicInfoMapper.selectCount(
                new QueryWrapper<CustomerBasicInfo>().eq("approval_status", "APPROVING"));
        long approvedCount = customerBasicInfoMapper.selectCount(
                new QueryWrapper<CustomerBasicInfo>().eq("approval_status", "APPROVED"));
        long rejectedCount = customerBasicInfoMapper.selectCount(
                new QueryWrapper<CustomerBasicInfo>().eq("approval_status", "REJECTED"));

        statistics.put("totalCount", totalCount);
        statistics.put("pendingCount", pendingCount);
        statistics.put("approvingCount", approvingCount);
        statistics.put("approvedCount", approvedCount);
        statistics.put("rejectedCount", rejectedCount);

        return statistics;
    }

    @Override
    public void cancelCustomerApplication(Long customerId, String reason, String currentUser) {
        CustomerBasicInfo customer = customerBasicInfoMapper.selectById(customerId);
        if (customer == null) {
            throw new RuntimeException("客户不存在");
        }

        String oldStatus = customer.getApprovalStatus();
        customer.setApprovalStatus("CANCELLED");
        customer.setUpdatedAt(new Date());

        customerBasicInfoMapper.updateById(customer);

        // 记录状态变更日志
        saveCustomerStatusLog(customer.getId(), customer.getCustomerName(), oldStatus,
                "CANCELLED", "取消申请：" + reason, currentUser);

        log.info("取消客户申请成功，客户ID：{}，客户名称：{}，原因：{}",
                customer.getId(), customer.getCustomerName(), reason);
    }

    @Override
    public void updateCustomerStatus(Long customerId, String status, String reason) {
        CustomerBasicInfo customer = customerBasicInfoMapper.selectById(customerId);
        if (customer == null) {
            throw new RuntimeException("客户不存在");
        }

        String oldStatus = customer.getApprovalStatus();
        customer.setApprovalStatus(status);
        customer.setUpdatedAt(new Date());

        if ("REJECTED".equals(status)) {
            // 可以在这里设置拒绝原因字段
        }

        customerBasicInfoMapper.updateById(customer);

        // 记录状态变更日志
        saveCustomerStatusLog(customer.getId(), customer.getCustomerName(), oldStatus,
                status, "系统自动更新状态", "system");

        log.info("客户状态更新成功，客户ID：{}，客户名称：{}，状态：{}",
                customer.getId(), customer.getCustomerName(), status);
    }

    @Override
    public void handleProcessCallback(Map<String, Object> callbackData) {
        try {
            Long customerId = Long.valueOf(callbackData.get("customerId").toString());
            String status = callbackData.get("approvalStatus").toString();
            String reason = callbackData.get("rejectReason") != null ?
                    callbackData.get("rejectReason").toString() : null;

            // 更新客户状态
            updateCustomerStatus(customerId, status, reason);

            log.info("处理客户审批流程回调成功，客户ID：{}，状态：{}", customerId, status);

        } catch (Exception e) {
            log.error("处理客户审批流程回调失败", e);
            throw new RuntimeException("处理流程回调失败: " + e.getMessage());
        }
    }

    /**
     * 拒绝客户申请
     */
    @Override
    public void rejectCustomer(String processInstanceId, String reason, String currentUser) {
        flowableFeign.rejectTask(processInstanceId, reason);
        customerBasicInfoMapper.updateByProcessInstanceIdReject(processInstanceId, reason, currentUser);
    }
/*
      * 根据创建人查询客户,查询我发起的
 */
    @Override
    public List<CustomerBasicInfo> queryByCreateBy(String createBy) {
        // 使用 QueryWrapper 构建查询条件
        QueryWrapper<CustomerBasicInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("create_by", createBy); // 假设数据库字段是 create_by
        return customerBasicInfoMapper.selectList(queryWrapper);
    }

    /**
     * 获取历史审批过的客户列表
     * @param currentUser
     * @return
     */
    @Override
    public List<CustomerBasicInfo> getHistoryCustomerApplications(String currentUser) {
        try{
        ResponseData<?> completedTasks = flowableFeign.getCompletedTasks(currentUser);
        if (!completedTasks.isSuccess() || completedTasks.getData() == null) {
            log.warn("获取历史任务失败或无数据，用户：{}", currentUser);
            return new ArrayList<>();
        }

        // 2. 从ResponseData中提取数据
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> taskList = (List<Map<String, Object>>) completedTasks.getData();

        if (taskList.isEmpty()) {
            log.info("用户 {} 没有历史任务", currentUser);
            return new ArrayList<>();
        }

        // 3. 提取所有的processInstanceId
        List<String> processInstanceIds = taskList.stream()
                .map(task -> (String) task.get("processInstanceId"))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        if (processInstanceIds.isEmpty()) {
            log.warn("历史任务中没有有效的processInstanceId，用户：{}", currentUser);
            return new ArrayList<>();
        }

        log.info("用户 {} 的历史任务包含 {} 个流程实例ID：{}", currentUser, processInstanceIds.size(), processInstanceIds);

        // 4. 根据processInstanceId查询CustomerBasicInfo
        QueryWrapper<CustomerBasicInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("process_instance_id", processInstanceIds);
        queryWrapper.orderByDesc("created_at");

        List<CustomerBasicInfo> customers = customerBasicInfoMapper.selectList(queryWrapper);

        log.info("根据流程实例ID查询到 {} 个客户信息", customers.size());
        return customers;

    } catch (Exception e) {
        log.error("获取待审批客户列表失败，用户：{}", currentUser, e);
        throw new RuntimeException("获取待审批客户列表失败: " + e.getMessage(), e);
    }
    }




    /**
     * 保存客户状态变更日志
     */
    private void saveCustomerStatusLog(Long customerId, String customerName, String oldStatus,
                                       String newStatus, String changeReason, String operator) {
        CustomerStatusLog log = new CustomerStatusLog();
        log.setCustomerId(customerId);
        log.setCustomerName(customerName);
        log.setOldStatus(oldStatus);
        log.setNewStatus(newStatus);
        log.setChangeReason(changeReason);
        log.setOperator(operator);
        log.setCreateTime(LocalDateTime.now());

        customerStatusLogMapper.insert(log);
    }

}
